package com.guojian.http.handle;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.util.Args;
import org.smartboot.http.HttpRequest;
import org.smartboot.http.server.Request;
import org.smartboot.http.server.RequestHook;
import org.springframework.http.HttpHeaders;

import com.google.common.base.Charsets;
import com.guojian.common.utils.StringUtilsx;

import lombok.Builder;
import lombok.Data;

/**
 * 
 * 构建org.apache.http.HttpRequest对象,利用httpClient进行代理访问
 * @author guoJian
 * 
 * if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)) {
		List<NameValuePair> nameValuePairList = new ArrayList<>();
		Map<String, String[]> paramsMap = request.getParameters();
		for (Map.Entry<String, String[]> params : paramsMap.entrySet()) {
			for (String value : params.getValue()) {
				nameValuePairList.add(new BasicNameValuePair(params.getKey(), value));
			}
		}
		requestEntity = new UrlEncodedFormEntity(nameValuePairList, Charsets.UTF_8);
	}
 *
 */

@Data
@Builder(builderMethodName = "create")
public class HttpSmartRequestBuilder {

	private HttpRequest request;
	private String targetUrl;

	public HttpUriRequest buildRequest() {
		Args.notNull(request, "HttpRequest");
		Args.notNull(targetUrl, "targetUrl");
		try {
			String contentType = getSimpleContentType(request.getHeader(HttpHeaders.CONTENT_TYPE));
			Request smartRequest = ((RequestHook) request).getRequest();
			HttpEntity requestEntity = getRequestEntity(contentType, getInputStream(smartRequest));
			HttpUriRequest httpUriRequest = RequestBuilder.create(request.getMethod()).setUri(targetUrl).setEntity(requestEntity).build();
			initTargetHeader(request, httpUriRequest);
			return httpUriRequest;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	private InputStream getInputStream(Request smartRequest) {
		try {
			return smartRequest.getBodyData() == null ? request.getInputStream() : new ByteArrayInputStream(smartRequest.getBodyData());
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	private HttpEntity getRequestEntity(String contentType, InputStream in) throws IOException {
		if (StringUtilsx.isNotBlank(contentType)) {
			return new InputStreamEntity(in, request.getContentLength(), ContentType.create(contentType, Charsets.UTF_8));
		}
		return new InputStreamEntity(in, request.getContentLength());
		//return new BufferedHttpEntity(httpEntity);
	}

	private String getSimpleContentType(String contentType) {
		if (StringUtils.isNotBlank(contentType) && contentType.contains(";")) {
			contentType = contentType.substring(0, contentType.indexOf(";"));
		}
		return contentType;
	}

	private void initTargetHeader(HttpRequest request, HttpUriRequest targetRequest) {
		for (String headerName : request.getHeaderNames()) {
			Collection<String> headerValues = request.getHeaders(headerName);
			headerValues.forEach(headerValue -> targetRequest.addHeader(headerName, headerValue));
		}
		targetRequest.removeHeaders("Content-Length");// httpClient会自动计算length
		targetRequest.removeHeaders("ETag");
		targetRequest.removeHeaders("Last-Modified");
		targetRequest.setHeader("Cache-Control", "no-cache");
	}

	public static Integer getContentLength(HttpRequest request) {
		Integer contentLength = -1;
		for (String headerName : request.getHeaderNames()) {
			String headerValue = request.getHeader(headerName);
			if (headerName.equalsIgnoreCase("content-length")) {
				try {
					contentLength = Integer.parseInt(headerValue);
				} catch (NumberFormatException e) {
					contentLength = -1;
				}
			}
		}
		return contentLength;
	}

	public static void main(String[] args) {
		HttpSmartRequestBuilder builder = HttpSmartRequestBuilder.create().request(null).targetUrl("1").build();
		System.out.println(builder);
	}
}
